package com.twoscreen;

import java.util.Date;
import java.util.logging.Logger;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.NotPersistent;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

@PersistenceCapable
public class PlayerScreen {
	@NotPersistent
	private static PersistenceManager pm = PMF.get().getPersistenceManager();
	
	@NotPersistent
	private static final Logger log = Logger.getLogger("com.twoscreen.PlayerScreen.java");
	
	@NotPersistent
	private static final String psIdPropertyName = "psID";
	
	@NotPersistent
	private static final String psValidUntilPropertyName = "validUntil";
	
	@NotPersistent
	private static final int validForMiliseconds = 86400000; //86400000 is 24 hours in milliseconds
	
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key key;
	
	@Persistent
	private long validUntil;
	
	public PlayerScreen(String psID) {
		Key key = KeyFactory.createKey(PlayerScreen.class.getSimpleName(), psID);
		this.key = key;
		this.validUntil = (new Date().getTime() + validForMiliseconds);
		pm.makePersistent(this);
		log.info("PlayerScreen added: psID: " + psID +
				" validUntil: " + validUntil);
	}
	
	public Key getKey() {
		return key;
	}

	public long getValidUntil() {
		return validUntil;
	}

	public static String getPsIdPropertyName() {
		return psIdPropertyName;
	}

	public static String getPsValidUntilPropertyName() {
		return psValidUntilPropertyName;
	}

	public static int getValidForMiliseconds() {
		return validForMiliseconds;
	}

	/**
	 * Create a new iTV player screen and receive the player screen ID in return
	 * @return Unique player screen ID
	 */
	public static String getPlayerScreenId() {
		//Get the unique ID
		log.info("Getting psID");
		String psID = getId(6);
		
		//Add the returned playerScreenID into the DataStore
		log.info("Got id: " + psID + " adding to datastore");
		new PlayerScreen(psID);
		
		return psID;
	}
	
	/**
	 * Generate a new unique ID
	 * @param length The length of the ID to create
	 * @return A String of the unique ID
	 */
	private static String getId(int length) {
		Boolean validId = false;
		String ID;
		
		do {
			ID = CodeGenerator.createID(length);
			log.info("Start exists test for: " + ID);
			boolean ex = exists(ID);
			log.info("Exists test result: " + ex + " for ID: " + ID);
			if (!ex) {
				validId = true;
			}
		} while (validId == false);
		
		return ID;
	}
	
	/**
	 * Check if the passed ID is in the data store
	 * @param id ID to check 
	 * @return Boolean true if exists
	 */
	private static boolean exists(String id) {
		boolean rtn = false;
		
		Key key = KeyFactory.createKey(PlayerScreen.class.getSimpleName(), id);
		try {
			log.info("Start of test");
			PlayerScreen result = pm.getObjectById(PlayerScreen.class, key);
			if (result != null) {
				rtn = true;
			}
		} catch (NullPointerException e) {
			log.info("Test failed " + e);
		} catch (JDOObjectNotFoundException e) {
			log.info("Test failed " + e);
		}
		
		//If there is nothing in the data store allow the ID
		return rtn;
	}
	

}
